home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * DISCLAIMER:
- *
- * This program is provided as a service to the programmer
- * community to demonstrate one or more features of the Amiga
- * personal computer. These code samples may be freely used
- * for commercial or noncommercial purposes.
- *
- * Commodore Electronics, Ltd ("Commodore") makes no
- * warranties, either expressed or implied, with respect
- * to the program described herein, its quality, performance,
- * merchantability, or fitness for any particular purpose.
- * This program is provided "as is" and the entire risk
- * as to its quality and performance is with the user.
- * Should the program prove defective following its
- * purchase, the user (and not the creator of the program,
- * Commodore, their distributors or their retailers)
- * assumes the entire cost of all necessary damages. In
- * no event will Commodore be liable for direct, indirect,
- * incidental or consequential damages resulting from any
- * defect in the program even if it has been advised of the
- * possibility of such damages. Some laws do not allow
- * the exclusion or limitation of implied warranties or
- * liabilities for incidental or consequential damages,
- * so the above limitation or exclusion may not apply.
- *
- */
-
-
- /*****************************************************************************
- *
- * FreeMap program creates a visual diagram of free memory
- *
- * =Robert J. Mical=
- * 9 January 1986
- *
- * Copyright (C) 1986, COMMODORE-AMIGA, INC.
- * All Rights Reserved
- *
- ****************************************************************************/
-
- #include "freemap.h"
-
- #define SCREENWIDTH 320
- #define SCREENHEIGHT 36
-
- #define STARTLINE 6
- #define STARTCOLUMN (2 + 4)
-
- #define LEFTOFFSET 6
-
- #define MENU_INFO 2
- #define MENU_REDISPLAY 1
- #define MENU_QUIT 0
-
- #define SCREENBYTEWIDTH 40
- #define MAPBYTEWIDTH 32 /* must be a power of two */
- #define MAX_BLOCK_COUNT ((512 * 1024) >> 6)
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- extern struct ExecBase *SysBase;
-
- struct TextAttr SafeFont =
- {
- "topaz.font",
- 8,
- 0,
- 0,
- };
-
-
- struct IntuiText PleaseText =
- {
- 0, 1,
- JAM2,
- 1, 1,
- NULL,
- "Please",
- NULL,
- };
-
-
- struct MenuItem PleaseItem =
- {
- NULL,
- 0, 0,
- 88, 9,
- ITEMTEXT | ITEMENABLED | HIGHCOMP,
- 0,
- (APTR)&PleaseText,
- NULL,
- 0,
- NULL,
- NULL,
- };
-
-
- struct Menu MapMenus[] =
- {
- {
- NULL,
- 10, 0,
- 48, 0,
- MENUENABLED,
- "Info",
- &PleaseItem,
- },
-
- {
- &MapMenus[0],
- 58, 0,
- 88, 0,
- MENUENABLED,
- "Redisplay",
- &PleaseItem,
- },
-
- {
- &MapMenus[1],
- 146, 0,
- 48, 0,
- MENUENABLED,
- "Quit",
- &PleaseItem,
- },
-
- };
-
-
- struct NewScreen MapScreen =
- {
- 0, 200 - SCREENHEIGHT,
- SCREENWIDTH, SCREENHEIGHT, 1,
- 0, 1,
- NULL,
- CUSTOMSCREEN,
- &SafeFont,
- NULL,
- NULL,
- NULL,
- };
-
-
- struct NewWindow MapWindow =
- {
- LEFTOFFSET, 0,
- (MAPBYTEWIDTH << 3) + 4, SCREENHEIGHT,
- -1, -1,
- MENUPICK | MENUVERIFY,
- SMART_REFRESH | BACKDROP | BORDERLESS | NOCAREREFRESH,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- 0, 0, 0, 0,
- CUSTOMSCREEN,
- };
-
-
- struct Screen *MyScreen;
- struct Window *MyWindow;
- SHORT BitsAvailable;
- SHORT BlockCount;
- BYTE BitsValue;
- SHORT WidthIndex;
- UBYTE *MemBlock;
- UBYTE *MapPointer;
-
- ShiftMask[8] =
- {
- 0xFF,
- 0X01,
- 0x03,
- 0x07,
- 0x0F,
- 0x1F,
- 0x3F,
- 0x7F,
- };
-
-
- RestartWindow()
- /* This routine clears the window and then draws the border */
- {
- SetRast(MyWindow->RPort, 0);
- Move(MyWindow->RPort, 0, 0);
- Draw(MyWindow->RPort, 0, SCREENHEIGHT - 1);
- Draw(MyWindow->RPort, (MAPBYTEWIDTH << 3)+4-1, SCREENHEIGHT - 1);
- Draw(MyWindow->RPort, (MAPBYTEWIDTH << 3) + 4 - 1, 0);
- Draw(MyWindow->RPort, 0, 0);
- }
-
-
- BumpMapPointer()
- /* This routine bumps the MapPointer variable, which variable contains the
- * pointer to the byte in the Screen's BitMap which is to receive the
- * next FreeMap bits.
- */
- {
- WidthIndex++;
- if (WidthIndex == MAPBYTEWIDTH)
- {
- /* We're at the right edge of the map window, so skip ahead
- * to the left edge of the next line
- */
- WidthIndex = 0;
- MapPointer += (SCREENBYTEWIDTH - MAPBYTEWIDTH + 1);
- }
- else MapPointer++;
- }
-
-
- ShiftInBits(bitcount)
- SHORT bitcount;
- /* This routine "shifts" the next set of bits into the memory map */
- {
- SHORT shift, bytecount;
-
- if (BitsAvailable & 0x7)
- {
- /* There's less than a whole byte available, so we must start
- * by shifting. Get the shift amount, which will be either all
- * of the bits that are available, or the block count if it's less
- * than the count of the available bits
- */
- if (bitcount > BitsAvailable) shift = BitsAvailable;
- else shift = bitcount;
-
- /* Shift the current contents of this byte of the map
- * out of the way of our new bits.
- */
- *MapPointer <<= shift;
-
- /* The above shift shifts zero bits in from the right.
- * If the current BitsValue is clear, leave them zero, else set our
- * new bits.
- */
- if (BitsValue) *MapPointer |= ShiftMask[shift];
-
- /* Reduce the block count by the number of bits we just arranged */
- bitcount -= shift;
-
- /* if we've used up this memory map byte, advance to the next one */
- if ((BitsAvailable -= shift) == 0)
- {
- BitsAvailable = 8;
- BumpMapPointer();
- }
-
- }
-
- /* Now that we've taken care of any partially completed Map bytes,
- * let's check for any whole bytes that we can set (speed!)
- */
- bytecount = bitcount >> 3;
- while (bytecount)
- {
- *MapPointer = BitsValue;
- BumpMapPointer();
- bytecount--;
- }
-
- /* Finally, do any remaining bitcount bits to be set */
- if (bitcount &= 0x7)
- {
- *MapPointer = BitsValue; /* Cheating, in a sense, but FAST! */
- BitsAvailable = 8 - bitcount;
- }
- }
-
-
- SHORT FindFreeBlock()
- /* This routine feels through the memory-free list, looking for a block
- * of free memory that is big enough to qualify as being a block.
- * A block starts on 64-byte boundaries and is 64-bytes wide. For a
- * block to be considered "free" all of the 64 bytes must be free
- */
- {
- SHORT firstwholeblock, nextrealblock;
-
- FOREVER
- {
- if (MemBlock == 0) return(0);
- firstwholeblock = (LONG)(MemBlock + 63) >> 6;
- nextrealblock = (LONG)( MemBlock
- + ((struct MemChunk *)MemBlock)->mc_Bytes ) >> 6;
-
- MemBlock = (UBYTE *)((struct MemChunk *)MemBlock)->mc_Next;
-
- if (firstwholeblock < nextrealblock)
- {
- BlockCount = nextrealblock - firstwholeblock;
- return(firstwholeblock);
- }
- }
- }
-
-
-
- SetTimer(sec, micro, timermsg)
- ULONG sec, micro;
- struct IOStdReq *timermsg;
- /* This routine simply sets the timer to interrupt us after secs.micros */
- {
- timermsg->io_Command = TR_ADDREQUEST; /* add a new timer request */
- timermsg->io_Actual = sec; /* seconds */
- timermsg->io_Length = micro; /* microseconds */
- SendIO(timermsg); /* post a request to the timer */
- }
-
-
-
- main()
- {
- struct MsgPort *timerport;
- struct IOStdReq *timermsg;
- struct MemHeader *MemHeader;
- SHORT NextFreeBlock, NextTakenBlock;
- ULONG wakeupbits, timerbit, windowbit;
- struct IntuiMessage *message;
- ULONG class;
- USHORT code;
- BOOL Redisplay;
-
-
- if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary(
- "intuition.library", 0)) == 0)
- {
- printf("NO LIBRARY");
- goto EXITING;
- }
-
- if ((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)) == 0)
- {
- printf("NO LIBRARY");
- goto EXITING;
- }
-
- if ((MyScreen = (struct Screen *)OpenScreen(&MapScreen)) == NULL)
- {
- printf("NO SCREEN");
- goto EXITING;
- }
-
- ShowTitle(MyScreen, FALSE);
- SetRGB4(&MyScreen->ViewPort, 0, 15, 12, 8);
- SetRGB4(&MyScreen->ViewPort, 1, 8, 0, 0);
-
- MapWindow.Screen = MyScreen;
- if ((MyWindow = (struct Window *)OpenWindow(&MapWindow)) == NULL)
- {
- printf("NO WINDOW");
- goto EXITING;
- }
- SetMenuStrip(MyWindow, &MapMenus[2]);
- SetFont(MyWindow->RPort, OpenFont(&SafeFont));
-
- Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 18);
- Text(&MyScreen->RastPort, "512K", 4);
- Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 26);
- Text(&MyScreen->RastPort, "MEMORY", 6);
- Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 34);
- Text(&MyScreen->RastPort, "MAP", 3);
- RestartWindow();
-
- timerport = (struct MsgPort *)CreatePort(0, 0);
- if (timerport == 0) goto EXITING;
-
- timermsg = (struct IOStdReq *)CreateStdIO(timerport);
- if (timermsg == 0) goto EXITING;
-
- if (OpenDevice(TIMERNAME, UNIT_VBLANK, timermsg, 0) != 0)
- goto EXITING;
-
- timerbit = 1 << timerport->mp_SigBit;
- windowbit = 1 << MyWindow->UserPort->mp_SigBit;
-
- SetTimer(2, 0, timermsg);
-
- Redisplay = TRUE;
-
- FOREVER
- {
- if (Redisplay)
- {
- /* This program draws the memory map information right into
- * the BitMap of the Screen, rather than using the graphics
- * support library routines to draw into the Window.
- * There is nothing illegal or immoral about doing this, but
- * is does require a thorough knowledge of how Intuition and
- * the graphics library create and manipulate the display.
- * In other words, this is *not* something that the novice
- * will want to do lightly, but the soon-to-be-expert may
- * want to examine as an example of how to do meta-graphics
- * in the Amiga window environment.
- */
- MapPointer = MyScreen->RastPort.BitMap->Planes[0];
- MapPointer += (SCREENBYTEWIDTH * 2 + 1);
-
- Forbid();
-
- do
- MemHeader = (struct MemHeader *)SysBase->MemList.lh_Head;
- while ((MemHeader->mh_Attributes & MEMF_CHIP) == 0);
-
- MemBlock = (UBYTE *)MemHeader->mh_First;
-
- BitsAvailable = 8;
- WidthIndex = 0;
- NextTakenBlock = 0;
-
- do
- {
- if (NextFreeBlock = FindFreeBlock())
- {
- BitsValue = 0;
- ShiftInBits(NextFreeBlock - NextTakenBlock);
- BitsValue = -1;
- ShiftInBits(BlockCount);
- NextTakenBlock = NextFreeBlock + BlockCount;
- }
- else ShiftInBits(MAX_BLOCK_COUNT - NextTakenBlock);
- }
- while (MemBlock);
-
- if (NextTakenBlock < MAX_BLOCK_COUNT)
- {
- BitsValue = 0;
- ShiftInBits(MAX_BLOCK_COUNT - NextTakenBlock);
- }
- Permit();
- }
-
- wakeupbits = Wait(timerbit | windowbit);
-
- if (wakeupbits & timerbit)
- {
- GetMsg(timerport); /* this does nothing more than "clear" */
- SetTimer(2, 0, timermsg);
- }
-
- if (wakeupbits & windowbit)
- {
- message = (struct IntuiMessage *)GetMsg(MyWindow->UserPort);
- class = message->Class;
- code = message->Code;
- ReplyMsg(message);
- switch (class)
- {
- case MENUVERIFY:
- Redisplay = FALSE;
- break;
- case MENUPICK:
- switch (MENUNUM(code))
- {
- case MENU_INFO:
- RestartWindow();
- Move(MyWindow->RPort,
- STARTCOLUMN, STARTLINE);
- Text(MyWindow->RPort,
- "Each pixel represents 64 bytes.", 31);
- Move(MyWindow->RPort,
- STARTCOLUMN + 20, STARTLINE + 9);
- Text(MyWindow->RPort,
- "If all bytes are free, the", 26);
- Move(MyWindow->RPort,
- STARTCOLUMN, STARTLINE + 18);
- Text(MyWindow->RPort,
- "pixel is dark, else it's light.", 31);
- Move(MyWindow->RPort,
- STARTCOLUMN + 20, STARTLINE + 28);
- Text(MyWindow->RPort,
- "This trinket by =RJMical=", 26);
- break;
- case MENU_REDISPLAY:
- RestartWindow();
- case NOMENU:
- Redisplay = TRUE;
- break;
- case MENU_QUIT:
- goto EXITING;
- }
- }
- }
- }
-
- EXITING:
- if (MyWindow) CloseWindow(MyWindow);
- if (MyScreen) CloseScreen(MyScreen);
- if (timerport)
- {
- Wait(timerbit);
- GetMsg(timerport);
-
- CloseDevice(timermsg);
- DeleteStdIO(timermsg);
- DeletePort(timerport);
- }
- }
-
-
-